﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.IO;
using System.Windows.Threading;
using System.Windows.Interop;

using DLLWrapper;

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int GetDllVersionPtr();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate bool OnTimerPtr();

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate bool GetFirmwareInfoPtr(ref HGDLLWrapper.FirmwareInfo Info);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate bool SetDevicePropertyPtr(uint device_id, int device_property, string prop_value, uint value_size);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate bool GetDevicePropertyPtr(uint device_id, int device_property, StringBuilder prop_value, ref int value_size);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate bool SetDeviceNotificationHandlerPtr(long hMsgWnd);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int DEVICE_PROP_CHANGED(uint device_id, int device_property, string prop_value, uint value_size);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate bool SetDeviceNotificationCallbackPtr(DEVICE_PROP_CHANGED device_prop_changed);


//#define WM_DEVICEPROCHANGE 0xFFEE
namespace BrightnessTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        IntPtr m_hModule;

        IntPtr MsgWndHandle;
        HwndSource MsgWndSrc;
        HwndSourceHook MsgWndMsgHook;



        GetDllVersionPtr GetDllVersion;
        GetFirmwareInfoPtr GetFirmwareInfo;
        SetDevicePropertyPtr SetDeviceProperty;
        GetDevicePropertyPtr GetDeviceProperty;
        SetDeviceNotificationHandlerPtr SetDeviceNotificationHandler;
        SetDeviceNotificationCallbackPtr SetDeviceNotificationCallback;
        OnTimerPtr OnTimer;

        /// <summary>
        /// /回调函数
        /// </summary>
        DEVICE_PROP_CHANGED dpc;
        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
            this.Closing += new System.ComponentModel.CancelEventHandler(MainWindow_Closing);
        }

        void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            HGDLLWrapper.FreeLibrary(m_hModule);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            MsgWndHandle = new WindowInteropHelper(this).Handle;
            MsgWndSrc = HwndSource.FromHwnd(MsgWndHandle);
            MsgWndMsgHook = new HwndSourceHook(WndMsgHookProc);
            MsgWndSrc.AddHook(MsgWndMsgHook);
            GetSubDir("./ThirdParty/");
            //SetDeviceNotificationHandler( this.handl)

            SetDeviceNotificationHandler(MsgWndHandle.ToInt32());

            dpc = new DEVICE_PROP_CHANGED(onDevPropChanged);
            GC.KeepAlive(dpc);
            SetDeviceNotificationCallback(dpc);

            //System.Timers.DispatcherTimer t = new System.Timers.Timer(1000);  //实例化Timer类，设置间隔时间为10000毫秒；  
            //t.Elapsed +=   new System.Timers.ElapsedEventHandler(time_out);  //到达时间的时候执行事件；  
            //t.AutoReset = true;  //设置是执行一次（false）还是一直执行(true)；  
            //t.Enabled = true;

            /// 获取亮度
            /// 
            StringBuilder proV = new StringBuilder(1024);
            int valueSize = 1;
            GetDeviceProperty(0, 0, proV, ref valueSize);
            string strValue = proV.ToString();
            //Int32 nValue = Int32.Parse( strValue);
  /// 
            DispatcherTimer _timer = new System.Windows.Threading.DispatcherTimer();
            _timer.Tick += new EventHandler(time_out);
            _timer.Interval = new TimeSpan(0, 0, 13);
            _timer.Start();

        }
        ///
        public bool devPropChangeIml(string prop_value)
        {
            label_prop_value.Content = prop_value;
            int nValue = int.Parse(prop_value);
            sliderBritness.Value = nValue;
            return true;
        }
        public int onDevPropChanged(uint device_id, int device_property, string prop_value, uint value_size)
        {
            devPropChangeIml(prop_value);
            return 1;
        }
        public void GetSubDir(string _path)
        {
            string[] subDirs = Directory.GetDirectories(_path);
            foreach (string subDir in subDirs)
            {
                string dllFile = subDir + "/BrightnessControl.dll";
                //               MessageBox.Show(subDir);
                IntPtr hModule = HGDLLWrapper.LoadLibrary(dllFile);
                GetFirmwareInfoPtr testF = (GetFirmwareInfoPtr)HGDLLWrapper.GetFunctionAddress(hModule, "GetFirmwareInfo", typeof(GetFirmwareInfoPtr));

                HGDLLWrapper.FirmwareInfo _info = new HGDLLWrapper.FirmwareInfo();
                _info.Init();
                bool bRet = testF(ref _info);
                if (bRet)
                {
                    label_DLL.Content = dllFile;
                    labelVersion.Content = char2string(_info.version);
                    labelVendor.Content = char2string(_info.vendor_name);
                    labelProduce.Content = char2string(_info.product_name);

                    m_hModule = hModule;
                    OnTimer = (OnTimerPtr)HGDLLWrapper.GetFunctionAddress(hModule, "OnTimer", typeof(OnTimerPtr));
                    GetDllVersion = (GetDllVersionPtr)HGDLLWrapper.GetFunctionAddress(hModule, "GetDllVersion", typeof(GetDllVersionPtr));
                    GetFirmwareInfo = (GetFirmwareInfoPtr)HGDLLWrapper.GetFunctionAddress(hModule, "GetFirmwareInfo", typeof(GetFirmwareInfoPtr));
                    SetDeviceProperty = (SetDevicePropertyPtr)HGDLLWrapper.GetFunctionAddress(hModule, "SetDeviceProperty", typeof(SetDevicePropertyPtr));
                    GetDeviceProperty = (GetDevicePropertyPtr)HGDLLWrapper.GetFunctionAddress(hModule, "GetDeviceProperty", typeof(GetDevicePropertyPtr));
                    SetDeviceNotificationHandler = (SetDeviceNotificationHandlerPtr)HGDLLWrapper.GetFunctionAddress(hModule, "SetDeviceNotificationHandler", typeof(SetDeviceNotificationHandlerPtr));
                    SetDeviceNotificationCallback = (SetDeviceNotificationCallbackPtr)HGDLLWrapper.GetFunctionAddress(hModule, "SetDeviceNotificationCallback", typeof(SetDeviceNotificationCallbackPtr));
                    break;
                }
                HGDLLWrapper.FreeLibrary(hModule);
            }

        }

        public static string char2string(byte[] _in)
        {
            string strAll = "";

            strAll = System.Text.Encoding.Default.GetString(_in);
            int nTail = strAll.IndexOf("\0");
            if (nTail > -1)
            {
                strAll = strAll.Substring(0, nTail);
            }
            return strAll;

        }
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            //string curDir = Directory.GetCurrentDirectory();
            //curDir += "\\ThirdParty\\";
            ////GetSubDir(curDir);
            //GetSubDir("./ThirdParty/");

            /// 函数指针
            /// 



            //int nd = HGDLLWrapper.GetDllVersion();
            //HGDLLWrapper.FirmwareInfo _info = new HGDLLWrapper.FirmwareInfo();
            //_info.Init();
            //HGDLLWrapper.GetFirmwareInfo(ref _info);
            //labelVersion.Content = char2string(_info.version);
            //labelVendor.Content = char2string(_info.vendor_name); 
            //labelProduce.Content = char2string(_info.product_name);


        }

        private IntPtr WndMsgHookProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            handled = false;
            //SetDeviceNotificationHandler( hwnd.ToInt32() );
            if (msg == 0xFFEE) /// change 消息
            {
                try
                {
                    int device_id = wParam.ToInt32();
                    int protype = lParam.ToInt32();
                    StringBuilder proV = new StringBuilder(1024);
                    int valueSize = 1;
                    GetDeviceProperty((uint)device_id, protype, proV, ref valueSize);
                    devPropChangeIml(proV.ToString());
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.WriteLine(ex.Message);
                    System.Diagnostics.Trace.WriteLine(ex.StackTrace);
                    System.Diagnostics.Trace.Flush();
                }

                handled = true;
            }

            return IntPtr.Zero;
        }

        public void time_out(object sender, EventArgs e)
        {
            //MessageBox.Show("OK!");
            OnTimer();
        }

        private void sliderBritness_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            int value = (int)e.NewValue;
            label_prop_value.Content = value.ToString();
        }
    }
}
